package com.laomou.password.db;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeMap;

public class SQLitePersistentObject {
    protected Context mContext;
    protected SQLiteHelper mHelper;
    private String TABLE_NAME;
    private HashMap<String, Object> COLUMN_VALUE = new HashMap<String, Object>();
    private Object mObject;

    public SQLitePersistentObject(Context context, Object classObj) {
        mObject = classObj;
        TABLE_NAME = classObj.getClass().getSimpleName();
        mContext = context;
        mHelper = new SQLiteHelper(context, mObject);
    }

    private void getObjectOutlet(Object classObj) {
        Field[] fields = classObj.getClass().getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                try {
                    field.setAccessible(true);
                    IDBOutlet outlet = field.getAnnotation(IDBOutlet.class);
                    if (outlet != null) {
                        String viewId = outlet.id();
                        COLUMN_VALUE.put(viewId, field.get(classObj));
                    }
                } catch (Exception e) {
                    Log.e("SQLitePersistentObject", "getDBColumn exception");
                }
            }
        }
    }

    public void save() {
        getObjectOutlet(mObject);
        if (canInsert()) {
            insert();
        } else {
            update();
        }
    }

    private boolean canInsert() {
        SQLiteDatabase db = mHelper.getReadableDatabase();
        Cursor c = null;
        try {
            c = db.rawQuery("SELECT * FROM " + TABLE_NAME + " WHERE _index=?", new String[]{COLUMN_VALUE.get("_index").toString()});
            return !c.moveToFirst();
        } catch (Exception e) {
        	Log.e("SQLitePersistentObject", "canInsert exception");
        } finally {
            if (c != null) {
                c.close();
            }
        }
        return true;
    }

    private void insert() {
        StringBuilder sql_key = new StringBuilder();
        StringBuilder sql_value = new StringBuilder();
        ArrayList<Object> objects = new ArrayList<Object>();
        sql_key.append("INSERT INTO " + TABLE_NAME);
        sql_key.append(" (");
        Iterator iterator = COLUMN_VALUE.entrySet().iterator();
        while (iterator.hasNext()) {
            TreeMap.Entry entry = (TreeMap.Entry) iterator.next();
            sql_key.append(entry.getKey());
            sql_key.append(",");
            sql_value.append("?");
            sql_value.append(",");
            objects.add(entry.getValue());
        }
        sql_key.deleteCharAt(sql_key.length() - 1);
        sql_key.append(") ");
        sql_key.append("VALUES (");
        sql_value.deleteCharAt(sql_value.length() - 1);
        sql_value.append(")");
        sql_key.append(sql_value);
        SQLiteDatabase db = mHelper.getWritableDatabase();
        try {
            db.execSQL(sql_key.toString(), objects.toArray());
        } catch (Exception e) {
        	Log.e("SQLitePersistentObject", "insert exception");
        } finally {
            db.close();
        }
    }

    public void update() {
        StringBuilder sql_key = new StringBuilder();
        ArrayList<Object> objects = new ArrayList<Object>();
        sql_key.append("UPDATE " + TABLE_NAME + " SET ");
        Object index = COLUMN_VALUE.get("_index");
        COLUMN_VALUE.remove("_index");
        Iterator iterator = COLUMN_VALUE.entrySet().iterator();
        while (iterator.hasNext()) {
            TreeMap.Entry entry = (TreeMap.Entry) iterator.next();
            sql_key.append(entry.getKey());
            sql_key.append("=?");
            sql_key.append(",");
            objects.add(entry.getValue());
        }
        sql_key.deleteCharAt(sql_key.length() - 1);
        sql_key.append(" WHERE _index=?");
        objects.add(index);
        SQLiteDatabase db = mHelper.getWritableDatabase();
        try {
            db.execSQL(sql_key.toString(), objects.toArray());
        } catch (Exception e) {
        	Log.e("SQLitePersistentObject", "update exception");
        } finally {
            db.close();
        }
    }
}